/**
 * 
 */
package com.xbang.attendance.entity.order;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;

import com.xbang.attendance.entity.system.MaintenanceStation;
import com.xbang.core.config.Note;
import com.xbang.core.dao.entity.BaseEntity;

/**
 * @author dev.zhang
 * 
 */
@Entity
public class PurchaseOrder extends BaseEntity implements Serializable {

	private static final long serialVersionUID = 4298981464821140311L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;

	@OneToMany(mappedBy = "purchaseOrder", cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.LAZY, targetEntity = PurchaseDetails.class)
	private Set<PurchaseDetails> purchaseDetails = new HashSet<PurchaseDetails>();

	/** 维修站 */
	@ManyToOne(cascade = { CascadeType.REFRESH }, fetch = FetchType.EAGER, targetEntity = MaintenanceStation.class)
	@JoinColumn(name = "maintenance_station", referencedColumnName = "id")
	private MaintenanceStation maintenanceStation;

	@OneToMany(mappedBy = "purchaseOrder", cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.LAZY, targetEntity = DeliveryOrder.class)
	private Set<DeliveryOrder> deliveryOrders;

	/** 订单单号 */
	@Note(value = "订单编号")
	private String orderNumber;

	/** 订单进入attendance日期 */
	private Date azkonobelDate;

	/** 订单日期 */
	@Note(value = "订单日期")
	private Date orderDate;

	private BigDecimal percentage;
	/* 排序 */
	private Integer compositor;

	@Transient
	private BigDecimal autoDeliveryNumber = new BigDecimal(0);

	@Transient
	private BigDecimal manualGenericDeliveryNumber = new BigDecimal(0);

	/**
	 * 拿到总数量
	 * 
	 * @return
	 */
	public BigDecimal getSumNumber() {
		BigDecimal sumProductAmount = new BigDecimal(0);

		Set<PurchaseDetails> tmpPurchaseDetails = getPurchaseDetails();

		for (Iterator<PurchaseDetails> iterator = tmpPurchaseDetails.iterator(); iterator.hasNext();) {
			PurchaseDetails purchaseDetails = iterator.next();

			sumProductAmount = sumProductAmount.add(purchaseDetails.getProductNumber() == null ? new BigDecimal(0) : purchaseDetails.getProductNumber());
		}

		return sumProductAmount;
	}

	/**
	 * 拿到自动百分比
	 * 
	 * @return
	 */
	public BigDecimal getAutoPercentage() {
		BigDecimal sumProductAmount = getSumNumber();
		if (autoDeliveryNumber.compareTo(new BigDecimal(0)) == 0 || sumProductAmount.compareTo(new BigDecimal(0)) == 0) {
			return new BigDecimal(0);
		}

		return new BigDecimal(autoDeliveryNumber.floatValue() / sumProductAmount.floatValue() * 100).setScale(2, BigDecimal.ROUND_DOWN);
	}

	/**
	 * 拿到自动匹配成功率
	 * 
	 * @return
	 */
	public BigDecimal getAutoSeccussPercentage() {
		BigDecimal sumProductAmount = autoDeliveryNumber.add(manualGenericDeliveryNumber);
		if (autoDeliveryNumber.compareTo(new BigDecimal(0)) == 0 || sumProductAmount.compareTo(new BigDecimal(0)) == 0) {
			return new BigDecimal(0);
		}

		return new BigDecimal(autoDeliveryNumber.floatValue() / sumProductAmount.floatValue() * 100).setScale(2, BigDecimal.ROUND_DOWN);
	}

	/**
	 * 拿到总的百分比
	 * 
	 * @return
	 */
	public BigDecimal getSumPercentage() {
		BigDecimal sumProductAmount = new BigDecimal(0);
		BigDecimal sumDeliveryAmount = new BigDecimal(0);

		Set<PurchaseDetails> tmpPurchaseDetails = getPurchaseDetails();

		for (Iterator<PurchaseDetails> iterator = tmpPurchaseDetails.iterator(); iterator.hasNext();) {
			PurchaseDetails purchaseDetails = iterator.next();

			sumProductAmount = sumProductAmount.add(purchaseDetails.getProductNumber() == null ? new BigDecimal(0) : purchaseDetails.getProductNumber());
			sumDeliveryAmount = sumDeliveryAmount.add(purchaseDetails.getDeliveryNumber() == null ? new BigDecimal(0) : purchaseDetails.getDeliveryNumber());
		}

		if (sumDeliveryAmount.compareTo(new BigDecimal(0)) == 0 || sumProductAmount.compareTo(new BigDecimal(0)) == 0) {
			return new BigDecimal(0);
		}

		// DataFormat.

		return new BigDecimal(sumDeliveryAmount.floatValue() / sumProductAmount.floatValue() * 100).setScale(2, BigDecimal.ROUND_DOWN);
	}

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the purchaseDetails
	 */
	public Set<PurchaseDetails> getPurchaseDetails() {
		return purchaseDetails;
	}

	/**
	 * @param purchaseDetails
	 *            the purchaseDetails to set
	 */
	public void setPurchaseDetails(Set<PurchaseDetails> purchaseDetails) {
		this.purchaseDetails = purchaseDetails;
	}

	/**
	 * @return the maintenanceStation
	 */
	public MaintenanceStation getMaintenanceStation() {
		return maintenanceStation;
	}

	/**
	 * @param maintenanceStation
	 *            the maintenanceStation to set
	 */
	public void setMaintenanceStation(MaintenanceStation maintenanceStation) {
		this.maintenanceStation = maintenanceStation;
	}

	/**
	 * @return the orderNumber
	 */
	public String getOrderNumber() {
		return orderNumber;
	}

	/**
	 * @param orderNumber
	 *            the orderNumber to set
	 */
	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}

	/**
	 * @return the azkonobelDate
	 */
	public Date getAzkonobelDate() {
		return azkonobelDate;
	}

	/**
	 * @param azkonobelDate
	 *            the azkonobelDate to set
	 */
	public void setAzkonobelDate(Date azkonobelDate) {
		this.azkonobelDate = azkonobelDate;
	}

	/**
	 * @return the orderDate
	 */
	public Date getOrderDate() {
		return orderDate;
	}

	/**
	 * @param orderDate
	 *            the orderDate to set
	 */
	public void setOrderDate(Date orderDate) {
		this.orderDate = orderDate;
	}

	/**
	 * @return the percentage
	 */
	public BigDecimal getPercentage() {

		if (percentage != null && percentage.compareTo(new BigDecimal(0)) > 0) {
			return percentage;
		}

		BigDecimal sumProductAmount = new BigDecimal(0);
		BigDecimal sumDeliveryAmount = new BigDecimal(0);

		Set<PurchaseDetails> tmpPurchaseDetails = getPurchaseDetails();

		for (Iterator<PurchaseDetails> iterator = tmpPurchaseDetails.iterator(); iterator.hasNext();) {
			PurchaseDetails purchaseDetails = iterator.next();

			sumProductAmount = sumProductAmount.add(purchaseDetails.getProductNumber() == null ? new BigDecimal(0) : purchaseDetails.getProductNumber());
			sumDeliveryAmount = sumDeliveryAmount.add(purchaseDetails.getDeliveryNumber() == null ? new BigDecimal(0) : purchaseDetails.getDeliveryNumber());
		}

		if (sumDeliveryAmount.compareTo(new BigDecimal(0)) == 0 || sumProductAmount.compareTo(new BigDecimal(0)) == 0) {
			return new BigDecimal(0);
		}

		// DataFormat.

		return new BigDecimal(sumDeliveryAmount.floatValue() / sumProductAmount.floatValue() * 100).setScale(2, BigDecimal.ROUND_DOWN);
	}

	/**
	 * @param percentage
	 *            the percentage to set
	 */
	public void setPercentage(BigDecimal percentage) {
		this.percentage = percentage;
	}

	/**
	 * @return the deliveryOrders
	 */
	public Set<DeliveryOrder> getDeliveryOrders() {
		return deliveryOrders;
	}

	/**
	 * @param deliveryOrders
	 *            the deliveryOrders to set
	 */
	public void setDeliveryOrders(Set<DeliveryOrder> deliveryOrders) {
		this.deliveryOrders = deliveryOrders;
	}

	public Integer getCompositor() {
		return compositor;
	}

	public void setCompositor(Integer compositor) {
		this.compositor = compositor;
	}

	/**
	 * @return the autoDeliveryNumver
	 */
	public BigDecimal getAutoDeliveryNumber() {
		return autoDeliveryNumber;
	}

	/**
	 * @param autoDeliveryNumber
	 *            the autoDeliveryNumver to set
	 */
	public void setAutoDeliveryNumber(BigDecimal autoDeliveryNumber) {
		this.autoDeliveryNumber = autoDeliveryNumber;
	}

	/**
	 * @return the manualGenericDeliveryNumber
	 */
	public BigDecimal getManualGenericDeliveryNumber() {
		return manualGenericDeliveryNumber;
	}

	/**
	 * @param manualGenericDeliveryNumber
	 *            the manualGenericDeliveryNumber to set
	 */
	public void setManualGenericDeliveryNumber(BigDecimal manualGenericDeliveryNumber) {
		this.manualGenericDeliveryNumber = manualGenericDeliveryNumber;
	}

}
